package com.miniserver.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import java.util.Collection;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.apache.commons.io.FileUtils;
/**
* 
* 
*/
public class DKeyDesEncrypt {

	private static String PASSWORD_CRYPT_KEY = "da4stg5rqbe8kpuc69xn31zym7wfh2";
    private final static String DES = "DES";
	
    /**
     * 加密
     * @param src 数据源
     * @param key 密钥，长度必须是8的倍数
     * @return 返回加密后的数据
     * @throws Exception
     */
    public static byte[] encrypt(byte[] src, byte[] key) throws Exception {
//DES算法要求有一个可信任的随机数源
        SecureRandom sr = new SecureRandom();
// 从原始密匙数据创建DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(key);
// 创建一个密匙工厂，然后用它把DESKeySpec转换成
// 一个SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
        SecretKey securekey = keyFactory.generateSecret(dks);
// Cipher对象实际完成加密操作
        Cipher cipher = Cipher.getInstance(DES);
// 用密匙初始化Cipher对象
        cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);
// 现在，获取数据并加密
// 正式执行加密操作
        return cipher.doFinal(src);
    }

    /**
     * 解密
     * @param src 数据源
     * @param key 密钥，长度必须是8的倍数
     * @return 返回解密后的原始数据
     * @throws Exception
     */
    public static byte[] decrypt(byte[] src, byte[] key) throws Exception {
// DES算法要求有一个可信任的随机数源
        SecureRandom sr = new SecureRandom();
// 从原始密匙数据创建一个DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(key);
// 创建一个密匙工厂，然后用它把DESKeySpec对象转换成
// 一个SecretKey对象
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
        SecretKey securekey = keyFactory.generateSecret(dks);
// Cipher对象实际完成解密操作
        Cipher cipher = Cipher.getInstance(DES);
// 用密匙初始化Cipher对象
        cipher.init(Cipher.DECRYPT_MODE, securekey, sr);
// 现在，获取数据并解密
// 正式执行解密操作
        return cipher.doFinal(src);
    }
    
    /**
     * 加密得到16进制字符串
     * @param password
     * @return
     */
    public final static synchronized String encryptBytes(byte[] password) {
        try {
            return byte2hex(encrypt(password,PASSWORD_CRYPT_KEY.getBytes()));
        } catch (Exception e) {
        }
        return null;
    }
    /**
     * 字节转16进制字符串
     * @param b
     * @return
     */
    public static String byte2hex(byte[] b) {

                 String hs = "";

                 String stmp = "";

                 for (int n = 0; n < b.length; n++) {

                     stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));

                     if (stmp.length() == 1)

                         hs = hs + "0" + stmp;

                     else

                         hs = hs + stmp;

                 }
                 return hs.toUpperCase();
            }
    
    /**
     * log日志简单加密
     * @param source
     * @return
     */
    public static String encryptLogString(String source) {        
        try {
			return byte2hex(source.getBytes("UTF-8"));
		} catch (UnsupportedEncodingException e) {
			return source;
		}
   }
    /**
     * log日志简单解密
     * @param source
     * @return
     */
    public static String decryptLogString(String source) {        
    	 try {
 			return new String(hex2byte(source.getBytes()),"UTF-8");
 		} catch (UnsupportedEncodingException e) {
 			return source;
 		}
   }

/**
 * 将16进制字节转为10进制字节
 * @param b
 * @return
 */
           public static byte[] hex2byte(byte[] b) {

               if ((b.length % 2) != 0)

                   throw new IllegalArgumentException("长度不是偶数");

               byte[] b2 = new byte[b.length / 2];

               for (int n = 0; n < b.length; n += 2) {

                   String item = new String(b, n, 2);

                   b2[n / 2] = (byte) Integer.parseInt(item, 16);

               }

               return b2;
           }
           /**
            * 加密文件
            * @param source
            * @param outFile
            */
           public static void encryptFile(File source,File outFile){
        	   try{
        		   FileInputStream fis = new FileInputStream(source);
        		   byte[] sb = new byte[fis.available()];
        		   fis.read(sb);
        		   fis.close();
        		   FileOutputStream fos = new FileOutputStream(outFile);
        		   fos.write(encryptBytes(sb).getBytes());
        		   fos.close();
        	   }catch(IOException ioe){ioe.printStackTrace();}
           }
           /**
            * 解密文件
            * @param source
            * @param outFile
            * @throws Exception
            */
           public static void decryptFile(File source,File outFile) throws Exception{
        	   try{        		   
        		   FileInputStream fis = new FileInputStream(source);
        		   byte[] sb = new byte[fis.available()];
        		   fis.read(sb);
        		   fis.close();
        		   FileOutputStream fos = new FileOutputStream(outFile);
        		   fos.write(decrypt(hex2byte(sb),PASSWORD_CRYPT_KEY.getBytes()));
        		   fos.close();
        	   }catch(IOException ioe){ioe.printStackTrace();}
           }
           
           public static byte[] decryptFileToBytes(File source) throws Exception{
        	   try{
        		   FileInputStream fis = new FileInputStream(source);
        		   byte[] sb = new byte[fis.available()];
        		   fis.read(sb);
        		   fis.close();        		  
        		   return decrypt(hex2byte(sb),PASSWORD_CRYPT_KEY.getBytes());        		   
        	   }catch(IOException ioe){ioe.printStackTrace();}
        	   return null;
           }
           
           public static void encryptConfigFile(String dirName,String [] suffix )
           {//new String[]{"xml","script","cfg","sql"}
	        	Collection<File> files  =FileUtils.listFiles(new File(dirName), suffix, true);		
	       		File binFile;
	       		for(File file : files)
	       		{
	       			binFile = new File(file.getAbsolutePath().concat("bin"));
	       			if (binFile.exists())
	       				binFile.delete();
	       			DKeyDesEncrypt.encryptFile(file, binFile);
	       			file.delete();
	       		}
           }
           
           public static void decryptConfigFile(String dirName,String [] suffix )
           {//new String[]{"xml","script","cfg","sql"}
	        	Collection<File> files  =FileUtils.listFiles(new File(dirName), suffix, true);		
	       		File binFile;
	       		for(File file : files)
	       		{
	       			binFile = new File(file.getAbsolutePath().substring(0,file.getAbsolutePath().length()-3));
	       			if (binFile.exists())
	       				binFile.delete();
	       			try {
						DKeyDesEncrypt.decryptFile(file, binFile);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}	       			
	       		}
           }
        
          public static void main(String[] a) throws Exception{ 
        	  /*
        	  String dataDir = "K:/VMWare/springsource/sts-3.2.0.RELEASE/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/tql/WEB-INF/props";
  			DKeyDesEncrypt.decryptConfigFile(dataDir, new String[] { "xmlbin","cfgbin","sqlbin"});
  			dataDir = "K:/VMWare/springsource/sts-3.2.0.RELEASE/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/tql/WEB-INF/data";
  			DKeyDesEncrypt.decryptConfigFile(dataDir,new String[]{"xmlbin","cfgbin","sqlbin"});*/
        	 /*System.out.println(DKeyDesEncrypt.encryptLogString("今天是2014/08/22"));
        	 System.out.println(DKeyDesEncrypt.decryptLogString(DKeyDesEncrypt.encryptLogString("今天是2014/08/22")));*/
          } 
}

